/*	Date:2017/7/29
 *	Author: Chunsheng Chen
 *	功能： 语法抽象树
 */


#ifndef _CM_ABSYN_H_
#define _CM_ABSYN_H_

#include "symbol.h"
#include "type.h"

extern int block;

struct ast{
	enum { cm_stmt }nodekind;
	struct ast* left;
	struct ast* right;
};

//对应 bison语法 中的stmt
struct CM_stmt{
	enum { cm_exp, cm_blockstmt, cm_decl,
			 cm_assign, cm_if, cm_while,
			 	 cm_for, cm_return} kind;
	union {
		struct CM_exp* exp;
		struct CM_stmtlist* sl;
		struct CM_decl* de;
		struct CM_assign* as;
		struct CM_if* i;
		struct CM_for* f;
		struct CM_while* w;
	}u;
};

struct CM_stmtlist{
	struct CM_stmt* stm;
	struct CM_stmtlist* next;
};

struct CM_assign{
	struct CM_var* var;
	struct CM_exp* exp;
};

struct CM_if{
	struct CM_exp* cond;
	struct CM_stmt* match;
	struct CM_stmt* unmatch;
};


struct CM_while{
	struct CM_exp* cond;
	struct CM_stmt* match;
};



struct CM_for{
	struct CM_assign* init;
	struct CM_exp* cond;
	struct CM_assign* after;
	struct CM_stmt* match;
};

struct CM_exp{
	enum {cm_plus, cm_minus, cm_mul, cm_div, cm_parent,
			cm_const_int, cm_const_float, cm_const_char, cm_arr,
			cm_var, cm_funcall, cmp_Less, cmp_LE, cmp_Equal, 
			cmp_Great, cmp_GE, cmp_NE} kind;
	union {
		struct symbol* id;
		struct CM_exp_st{
			struct CM_exp* left;
			struct CM_exp* right;
		}*kid;
		struct CM_var* var;
		struct CM_fun_call{
			struct symbol* funName;
			struct CM_varlist* paramlist;
		}*fun;
	}u;
};


struct CM_var{
	enum { var_abs_id, var_abs_array, var_abs_struct } kind;
	union{
		struct CM_arr_get{
			struct symbol* id;
			struct CM_exp* index;
		}*arr;
		struct CM_struct_get{
			struct symbol* sym;
			struct symbol* field;
		}*stu;
		struct symbol* sym;
	}u;
};

struct CM_decl{
	enum { cm_typedecl, cm_vardecl, cm_fundecl } kind;
	struct symbol* sym;
	union{
		struct CM_typedecl* st;
		struct CM_vardecl* type;
		struct CM_fundecl* fun;
	}u;
};

struct CM_typedecl{
	struct symbol* sym;
	struct CM_vardeclist* list;
};

struct CM_vardecl{
	struct CM_type* type;
	union{
		struct symbol* sym;
		struct ArrDecl{
			struct symbol* sym;
			struct CM_exp* size;
		}*arr;
	}u;
};

struct CM_fundecl{
	struct CM_type* type;
	struct symbol* funName;
	struct CM_vardeclist* paramlist;
	struct CM_stmtlist* stmt;
};

struct CM_varlist{
	struct CM_exp* exp;
	struct CM_varlist* next;
};

struct CM_vardeclist{
	struct CM_vardecl* stfield;
	struct CM_vardeclist* next;
};

struct CM_type{
	enum { cm_simple, cm_struct, cm_ty_arr} kind;
	struct symbol* type;
};


struct CM_type* newtype(int, struct symbol*);
struct CM_vardecl* newvardecl(struct CM_type*, struct symbol*);
struct CM_vardecl* newarrdecl(struct CM_type*, struct symbol*, struct CM_exp*);
struct CM_vardeclist* newvardeclist(struct CM_vardecl*, struct CM_vardeclist*);
struct CM_typedecl* newtypedecl(struct symbol*, struct CM_vardeclist*);
struct CM_decl* newdecl(int, void*);
struct CM_exp* newexp(int, void*, void*);
struct CM_stmt* newstmt(int, void*);
struct CM_stmtlist* newstmtlist(struct CM_stmt*, struct CM_stmtlist*);
struct CM_assign* newassign(struct CM_var*, struct CM_exp*);
struct CM_if* newif(struct CM_exp*, struct CM_stmt*, struct CM_stmt*);
struct CM_while* newwhile(struct CM_exp*, struct CM_stmt*);
struct CM_for* newfor(struct CM_assign*, struct CM_exp*, struct CM_assign*, struct CM_stmt*);
struct CM_var* newvar(int, struct symbol*, void*);
struct CM_fundecl* newfundecl(struct CM_type*, struct symbol*, struct CM_vardeclist*, struct CM_stmtlist*);
struct CM_varlist* newvarlist(struct CM_exp*, struct CM_varlist*);
int getCmpOp(int);


#endif
